前情提要
今天 npm 圈子鸡犬不宁,原因是一个不过 11 行的工具函数 left-pad 被作者从 npm 上撤下,所有直接和间接依赖它的包就这么齐刷刷挂了,包括 babel 和 react-native 这样每天安装数万的热门项目。
而 Azer 删除他所有的 npm 包又是另一个故事:Azer 写了一个工具叫 kik 发布在 npm 上,这天有个同名的公司律师找上门要求他删掉,Azer 不从,这律师就找上 npm,npm 把包的管理权限转给了这家公司——当然,Azer 就怒了,从 npm 上解放了所有自己发布的包。
是的,就是这样 ╮(╯_╰)╭
small module 的错?
babel 很快就发布了修正。然而抛开这两个故事不去讨论,鉴于现在各种组件的依赖树之深,这件事暴露出的问题(一直都在,只是没有这么痛地领悟过)已经让人无法安心地 npm install
了——更多的项目都不可能像 babel 这样活跃,第一时间发布修正。
各种担忧、质疑指向 npm 社区一直提倡和推动的 small module 和 semver 理念。这个方向错了么?也有人怪罪 npm unpublish
是万恶之源,这么想就有点表面了。
得救之道,就在其中
Isaacs 在 left-pad 的 Issue 里回复说“不要依赖于其他人”,附了关于 bundledDependencies 的链接,并且最后再次强调 small module 依然是合理的哲学。
这篇回复其实比较含糊,甚至看上去有点矛盾。Rollup 作者讲得更明白些,解决之道就一句话:
无论你是否面向浏览器,将所有依赖都打包进最终的发布代码。
这么做将使你的项目仅仅在打包的时候依赖那些 dependencies,一旦发布完成,就不再需要依赖树上的所有作者们保持他们的任何承诺。这就是 Isaacs 所说:不要依赖于其他 人。
事实上 Atom 也在受影响之列,但除了 Atom 的开发者之外,用户是没有感觉的——就这么简单。
此原则除了可以解决这次的 left-pad 灾难之外,还有成堆的好处,哪怕每一项都不是杀手级的,这么堆起来也还是很可观的:
节省
npm install
的时间。依次去下载整个依赖树是很耗时间的,而且还附带下载了更多的 README、package.json 之类。这些磁盘空间也可以省下来了。启动更快。你知道 Nodejs 的
require()
执行慢成狗么?你的包更加可靠。依赖树中的 bug 不能靠用户自行
npm update
来修复了,你得自己重新打包发版本,但是再也不用担心出 left-pad 这种幺蛾子,哪个更重要?也更加安全。理论上,npm 托管的那些代码随时可能被注入恶意代码,比如现在 Azer 撤下来的包,不少已经被其他人重新发布上去,可是天知道都是谁放了些什么代码……用户只不过
npm install
了一下。解除了用户为你的代码打包的负担。 负担其实并不是我们担心的,只是如果用户喜欢用 webpack 打包而我们的代码是 browserify 圈的呢?PouchDB 就碰上了这种情况。
新的习惯
养成新的习惯,开始为你发布的代码做预打包吧。bundledDependencies 已经等候多时了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。